package main

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"github.com/yourusername/rss-reader-ai/internal/config"
	"github.com/yourusername/rss-reader-ai/internal/db"
	"github.com/yourusername/rss-reader-ai/internal/handler"
	"github.com/yourusername/rss-reader-ai/internal/repository"
	"github.com/yourusername/rss-reader-ai/internal/scheduler"
	"github.com/yourusername/rss-reader-ai/internal/service"
	"go.uber.org/zap"
)

// =====================================================
// main - 主程序入口
// =====================================================

func main() {
	// 1. 加载配置文件
	log.Println("📦 正在加载配置文件...")
	cfg, err := config.LoadConfig("configs/config.yaml")
	if err != nil {
		log.Fatalf("❌ 配置文件加载失败: %v", err)
	}
	log.Println("✅ 配置文件加载成功")

	// 2. 初始化日志
	logger, err := zap.NewProduction()
	if err != nil {
		log.Fatalf("❌ 日志初始化失败: %v", err)
	}
	defer logger.Sync()

	// 3. 初始化数据库连接
	log.Println("🔌 正在连接数据库...")
	database, err := db.InitDB(cfg)
	if err != nil {
		log.Fatalf("❌ 数据库连接失败: %v", err)
	}
	log.Println("✅ 数据库连接成功")

	// 4. 设置 Gin 运行模式
	gin.SetMode(cfg.Server.Mode)

	// 5. 创建 Gin 路由器
	router := gin.New()

	// 6. 配置中间件
	setupMiddlewares(router, cfg)

	// 7. 依赖注入 - 创建所有组件实例
	log.Println("🏗️  正在初始化应用组件...")
	feedService, feedRepo := setupHandlers(router, database, cfg)
	log.Println("✅ 应用组件初始化完成")

	// 8. 创建并启动定时任务调度器
	log.Println("⏰ 正在初始化定时任务调度器...")
	sched := scheduler.NewScheduler(feedService, feedRepo, logger)
	if err := sched.Start(); err != nil {
		log.Fatalf("❌ 定时任务启动失败: %v", err)
	}

	// 9. 启动 HTTP 服务器（非阻塞）
	addr := fmt.Sprintf("%s:%d", cfg.Server.Host, cfg.Server.Port)
	srv := &http.Server{
		Addr:    addr,
		Handler: router,
	}

	// 在 goroutine 中启动服务器
	go func() {
		log.Printf("🚀 服务器启动成功! 监听地址: http://%s\n", addr)
		log.Printf("📚 API 文档: http://localhost:%d/api/feeds\n", cfg.Server.Port)
		log.Println("💡 按 Ctrl+C 停止服务器")
		
		if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("❌ 服务器启动失败: %v", err)
		}
	}()

	// 10. 优雅关闭机制
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit // 阻塞等待信号

	log.Println("\n🛑 收到停止信号，正在优雅关闭...")

	// 停止定时任务调度器
	sched.Stop()

	// 关闭 HTTP 服务器
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := srv.Shutdown(ctx); err != nil {
		log.Printf("❌ 服务器关闭失败: %v", err)
	}

	// 关闭数据库连接
	sqlDB, err := database.DB.DB()
	if err == nil {
		sqlDB.Close()
	}

	log.Println("✅ 服务器已安全关闭")
}

// =====================================================
// setupMiddlewares - 配置中间件
// =====================================================

func setupMiddlewares(router *gin.Engine, cfg *config.Config) {
	log.Println("🔧 正在配置中间件...")

	// 1. 日志中间件 - 记录每个请求的详细信息
	router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
		return fmt.Sprintf("[%s] %s %s %d %s %s\n",
			param.TimeStamp.Format("2006-01-02 15:04:05"),
			param.Method,
			param.Path,
			param.StatusCode,
			param.Latency,
			param.ErrorMessage,
		)
	}))

	// 2. 错误恢复中间件 - 捕获 panic 并返回 500 错误
	router.Use(gin.Recovery())

	// 3. CORS 跨域中间件 - 允许前端跨域访问
	corsConfig := cors.Config{
		AllowOrigins:     cfg.CORS.AllowOrigins,
		AllowMethods:     cfg.CORS.AllowMethods,
		AllowHeaders:     cfg.CORS.AllowHeaders,
		AllowCredentials: cfg.CORS.AllowCredentials,
		MaxAge:           time.Duration(cfg.CORS.MaxAge) * time.Second,
	}
	router.Use(cors.New(corsConfig))

	log.Println("  ✓ 日志中间件已启用")
	log.Println("  ✓ 错误恢复中间件已启用")
	log.Printf("  ✓ CORS 中间件已启用 (允许的源: %v)\n", cfg.CORS.AllowOrigins)
}

// =====================================================
// setupHandlers - 依赖注入并注册路由
// =====================================================

func setupHandlers(router *gin.Engine, database *db.Database, cfg *config.Config) (service.FeedService, repository.FeedRepository) {
	// ==================== 第一层: Repository 层 ====================
	// Repository 直接依赖数据库连接
	log.Println("  📂 创建 Repository 层...")
	feedRepo := repository.NewFeedRepository(database.DB)
	articleRepo := repository.NewArticleRepository(database.DB)
	tagRepo := repository.NewTagRepository(database.DB)
	log.Println("    ✓ FeedRepository")
	log.Println("    ✓ ArticleRepository")
	log.Println("    ✓ TagRepository")

	// ==================== 第二层: Service 层 ====================
	// Service 依赖 Repository 和配置
	log.Println("  🎯 创建 Service 层...")

	// FeedService - 依赖 FeedRepository、ArticleRepository
	feedService := service.NewFeedService(feedRepo, articleRepo)
	log.Println("    ✓ FeedService")

	// ArticleService - 依赖 ArticleRepository、TagRepository、FeedRepository
	articleService := service.NewArticleService(articleRepo, tagRepo, feedRepo)
	log.Println("    ✓ ArticleService")

	// AIService - 依赖 ArticleRepository、TagRepository、Config
	aiService := service.NewAIService(articleRepo, tagRepo, cfg)
	log.Println("    ✓ AIService")

	// ==================== 第三层: Handler 层 ====================
	// Handler 依赖 Service
	log.Println("  🌐 创建 Handler 层...")

	feedHandler := handler.NewFeedHandler(feedService)
	articleHandler := handler.NewArticleHandler(articleService)
	aiHandler := handler.NewAIHandler(aiService)

	log.Println("    ✓ FeedHandler")
	log.Println("    ✓ ArticleHandler")
	log.Println("    ✓ AIHandler")

	// ==================== 注册路由 ====================
	log.Println("  🛣️  注册 API 路由...")

	// 创建 API 路由组 (所有 API 都在 /api 前缀下)
	api := router.Group("/api")

	// 注册各个模块的路由
	feedHandler.RegisterRoutes(api)       // /api/feeds/*
	articleHandler.RegisterRoutes(api)    // /api/articles/*
	aiHandler.RegisterRoutes(api)         // /api/ai/*

	log.Println("    ✓ 订阅源 API: /api/feeds/*")
	log.Println("    ✓ 文章 API: /api/articles/*")
	log.Println("    ✓ AI 摘要 API: /api/ai/*")

	// 健康检查接口
	router.GET("/health", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"status": "ok",
			"timestamp": time.Now().Unix(),
		})
	})
	log.Println("    ✓ 健康检查: /health")

	// 返回需要的服务和仓库实例
	return feedService, feedRepo
}
